<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clock</title>
</head>
<style>
    * {
        margin: 0px;
        padding: 0px;
        box-sizing: border-box;
    }
    body {
        height: 100vh;
        display: flex;
        /* 保持在画布中心 */
        justify-content: center;
        align-items: center;
        background: #333;
    }
    .clock {
        width: 300px;
        height: 300px;
        background-color: rgb(15,15,15);
        /* 圆角 */
        border-radius: 50px;
    }
</style>
<body>
    <div class="clock">
        <canvas width="300px" height="300px" id="canvas"></canvas>
    </div>
    <script>
        var canvas = document.getElementById("canvas");     // 获取元素，建立联系
        var ctx = canvas.getContext("2d");  // 联系上下文
        // 函数定义
        function drawPanel()                // 绘制底盘
        {
            ctx.translate(150, 150);
            // 开始绘制
            ctx.beginPath();
            ctx.arc(0, 0, 130, 0, 2 * Math.PI);
            ctx.fillStyle = "white";
            ctx.fill();
        }
        function hourNum()
        {
            // 时钟数字
            var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
            // 开始绘制
            ctx.beginPath();
            ctx.font = "30px fangsong";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillStyle = "black";
            for (var i = 0; i < arr.length; i++)
            {
                // 循环绘制数字
                ctx.fillText(
                    arr[i],
                    108 * Math.cos(((i * 30 - 60) * Math.PI) / 180),
                    108 * Math.sin(((i * 30 - 60) * Math.PI) / 180)
                );
            }
        }
        function centerDot()
        {
            ctx.beginPath();
            ctx.arc(0, 0, 8, 0, 2 * Math.PI);
            ctx.fill();
            ctx.beginPath();
            ctx.fillStyle = "gray";
            ctx.arc(0, 0, 5, 0, 2 * Math.PI);
            ctx.fill();
        }
        function hourHand(hours, minutes)       // 绘制时针
        {
            // 应该旋转的角度，默认时钟为指向12点
            var radius = ((2 * Math.PI) / 12) * hours + (((1 / 6) * Math.PI) / 60) * minutes;
            // 保存当前状态，使旋转后能回到当初状态
            ctx.save();
            ctx.beginPath();
            // 针的宽度
            ctx.lineWidth = 5;
            // 针头
            ctx.lineCap = "round";
            ctx.strokeStyle = "black";
            // 旋转
            ctx.rotate(radius);
            // 画线
            ctx.moveTo(0, 0);
            ctx.lineTo(0, -50);
            ctx.stroke();
            // 返回初始状态
            ctx.restore();
        }
        function minuteHand(minutes)       // 绘制分针
        {
            // 应该旋转的角度，默认时钟为指向12点
            var radius = ((2 * Math.PI) / 60) * minutes;
            // 保存当前状态，使旋转后能回到当初状态
            ctx.save();
            ctx.beginPath();
            // 针的宽度
            ctx.lineWidth = 3;
            // 针头
            ctx.lineCap = "round";
            ctx.strokeStyle = "black";
            // 旋转
            ctx.rotate(radius);
            // 画线
            ctx.moveTo(0, 0);
            ctx.lineTo(0, -70);
            ctx.stroke();
            // 返回初始状态
            ctx.restore();
        }
        function secondHand(seconds)       // 绘制秒针
        {
            // 应该旋转的角度，默认时钟为指向12点
            var radius = ((2 * Math.PI) / 60) * seconds;
            // 保存当前状态，使旋转后能回到当初状态
            ctx.save();
            ctx.beginPath();
            // 针的宽度
            ctx.lineWidth = 1;
            // 针头
            ctx.lineCap = "round";
            ctx.strokeStyle = "red";
            // 旋转
            ctx.rotate(radius);
            // 画线
            ctx.moveTo(0, 0);
            ctx.lineTo(0, -90);
            ctx.stroke();
            // 返回初始状态
            ctx.restore();
        }
        // 获取当前时间
        function update()
        {
            var time = new Date();
            var hours = time.getHours();
            var minutes = time.getMinutes();
            var seconds = time. getSeconds();
            // 保存canvas状态
            ctx.save();
            drawPanel();
            hourNum();
            secondHand(seconds);
            minuteHand(minutes);
            hourHand(hours, minutes);
            centerDot();
            // 恢复canvas状态
            ctx.restore();
        }
        update();
        // 开启定时器，时钟运转
        setInterval(() =>
        {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            update();
        }, 1000);
    </script>
</body>
</html>